import os

from bean.Constants import Constants
from bean.FieldInfo import FieldInfo
from bean.TableInfo import TableInfo

from builder.CommentBuilder import CommentBuilder
from utils.StringUtils import uppercase_first_char


class QueryBuilder:

    @staticmethod
    def execute_build(table_info: TableInfo) -> None:
        if not os.path.exists(Constants.get_instance().PARAM_PATH):
            os.makedirs(Constants.get_instance().PARAM_PATH)

        new_filed_cache = []
        filed_lst = list(table_info.field_map.values())

        with open(
                Constants.get_instance().PARAM_PATH + f"{table_info.bean_name}{Constants.get_instance().SUFFIX_BEAN_PARAM}.java",
                "w", encoding="utf-8") as f:
            """
            导包和定义包名
            """
            f.write(f"package {Constants.get_instance().PACKAGE_PARAM};\n")
            if table_info.have_date or table_info.have_date_time:
                f.write("\nimport java.util.Date;\n")
            if table_info.have_big_decimal:
                f.write("import java.math.BigDecimal;\n")
            CommentBuilder.build_class_comment(f, table_info.comment, True)
            f.write("\n")
            """
            开始定义类
            """
            f.write(f"public class {table_info.bean_name}{Constants.get_instance().SUFFIX_BEAN_PARAM} extends BaseQuery{{\n")

            """
            遍历table_info的字段写入table_info的类中
            """
            for j in table_info.field_map.values():

                f.write("\n")
                CommentBuilder.build_comment_and_format(f, j, True)
                f.write("\n")
                f.write(f"\tprivate {j.java_type} {j.property_name};")
                f.write("\n")
                if j.java_type == "String":
                    f.write("\n")
                    f.write(
                        f"\tprivate {j.java_type} {j.property_name}{Constants.get_instance().SUFFIX_BEAN_PARAM_FUZZY};")
                    f.write("\n")

                    filed_info = QueryBuilder.create_extend_filed(j, Constants.get_instance().SUFFIX_BEAN_PARAM_FUZZY)
                    new_filed_cache.append(filed_info)

                elif j.java_type == "Date":
                    f.write("\n")
                    f.write(
                        f"\tprivate {j.java_type} {j.property_name}{Constants.get_instance().SUFFIX_BEAN_PARAM_TIME_START};")
                    f.write("\n")
                    f.write("\n")
                    f.write(
                        f"\tprivate {j.java_type} {j.property_name}{Constants.get_instance().SUFFIX_BEAN_PARAM_TIME_END};")
                    f.write("\n")

                    filed_info = QueryBuilder.create_extend_filed(
                        j, Constants.get_instance().SUFFIX_BEAN_PARAM_TIME_START
                    )
                    new_filed_cache.append(filed_info)
                    filed_info = QueryBuilder.create_extend_filed(
                        j, Constants.get_instance().SUFFIX_BEAN_PARAM_TIME_END
                    )
                    new_filed_cache.append(filed_info)

            filed_union_lst = set(new_filed_cache + filed_lst)
            table_info.extend_fields = new_filed_cache

            for j in filed_union_lst:
                f.write("\n")
                f.write(f"\tpublic {j.java_type} get{uppercase_first_char(j.property_name)}(){{\n")
                f.write(f"\t\treturn this.{j.property_name};")
                f.write("\n\t}\n")
                f.write("\n")
                f.write(
                    f"\tpublic void set{uppercase_first_char(j.property_name)}({j.java_type} {j.property_name}){{\n")
                f.write(f"\t\tthis.{j.property_name} = {j.property_name};")
                f.write("\n\t}")
                f.write("\n")

            f.write("\n}")

    @staticmethod
    def create_extend_filed(field_info: FieldInfo, suffix: str) -> FieldInfo:
        new_filed: FieldInfo = FieldInfo()
        new_filed.property_name = field_info.property_name + suffix
        new_filed.java_type = field_info.java_type
        new_filed.sql_type = field_info.sql_type
        new_filed.java_type = field_info.java_type
        new_filed.filed_name = field_info.filed_name
        return new_filed
